/*****************************************************************************
*                     Organizacion de Datos - 75.06                          *
*                         Catedra Lic. Servetto                              *
*            Facultad de Ingenieria - Universidad de Buenos Aires            *
******************************************************************************/

#include "AdministradorMetadata.h"
#include "ConexionCapaMetadata.h"
#include "../Comun/Clase.h"

#include <string>
#include <list>

using namespace Comun;

namespace CapaConsulta 
{
	
	AdministradorMetadata::AdministradorMetadata(string nombreClase)
	{
		this->existeClase = ConexionCapaMetadata::ExisteClase(nombreClase, &this->ClaseMetadata);
	}
	
	AdministradorMetadata::~AdministradorMetadata()
	{
		delete this->ClaseMetadata;
	}
	
	bool AdministradorMetadata::ExisteClase()
	{
		return this->existeClase;
	}
	
	// TODO: Hacer mas complejas las validaciones
	bool AdministradorMetadata::ElValorDelAtributoEsCorrecto(string nombreAtributo, string valorAtributo)
	{
		if (!this->existeClase)
			return false;
		
		Atributo* atributo = this->BuscarAtributoPorNombre(nombreAtributo);
		
		long shortLong;
		short corto;
		
		short anio;
		short mes;
		short dia;
		
		switch (atributo->Tipo)
		{
			case Cadena:
				if (valorAtributo[0] != '\'')
					return false;
				if (valorAtributo[valorAtributo.length() - 1] != '\'')
					return false;
				return (valorAtributo.length() < 258);

			case Caracter:
				return (valorAtributo.length() == 1);

			case Entero:
				shortLong = atoi(valorAtributo.c_str());
				corto = (short) atoi(valorAtributo.c_str());
				return (corto == shortLong);

			case EnteroLargo:
				return true;

			case Fecha:
				if (valorAtributo[0] != '\'')
					return false;
				if (valorAtributo[valorAtributo.length() - 1] != '\'')
					return false;
				if (valorAtributo.substr(3,1) != "/" || valorAtributo.substr(6,1) != "/")
					return false;
				anio = (short) atoi(valorAtributo.substr(7,4).c_str());
				mes = (short) atoi(valorAtributo.substr(4,2).c_str());
				dia = (short) atoi(valorAtributo.substr(1,2).c_str());
				if (anio < 0 || anio > 9999)
					return false;
				if (mes < 1 || mes > 12)
					return false;
				if (mes == 1 || mes == 3 || mes == 5 || mes == 7 || mes == 8 || mes == 10 || mes == 12)
					if (dia < 0 || dia > 31)
						return false;
				if (mes == 4 || mes == 6 || mes == 9 || mes == 11)
					if (dia < 0 || dia > 30)
						return false;
				if (mes == 2)
					if (dia < 0 || dia > 29) //Chequear biciestos
						return false;
				return true;

			case Booleano:
				if (valorAtributo == "0" || valorAtributo == "1")
					return true;
				return false;

			case Real:
				return true;

			default:
				return false;
		}
		
		return false;
	}
	
	bool AdministradorMetadata::EsAtributoDeLaClase(string nombreAtributo)
	{
		if (!this->existeClase)
			return false;
		
		for (list<Atributo>::iterator i = this->ClaseMetadata->Miembros->begin(); i != this->ClaseMetadata->Miembros->end(); ++i)
		{
			Atributo atributo = *i;
			if (atributo.Nombre == nombreAtributo)
				return true;
		}
		
		return false;
	}
	
	Atributo* AdministradorMetadata::BuscarAtributoPorNombre(string nombreAtributo)
	{
		if (!this->existeClase)
		{
			cerr << "No existe a clase donde buscar el " << nombreAtributo << "." << endl;
			throw new exception();
		}
		
		for (list<Atributo>::iterator i = this->ClaseMetadata->Miembros->begin(); i != this->ClaseMetadata->Miembros->end(); ++i)
		{
			Atributo atributo = *i;
			if (atributo.Nombre == nombreAtributo)
				return new Atributo(atributo);
		}
		
		cerr << "No se encuentra el atributo " << nombreAtributo << " en la clase " << this->ClaseMetadata->NombreClase << "." << endl;
		throw new exception();
	}
}
